package com.xs.ahoi.hcxs.ui.activity;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.google.common.collect.Lists;
import com.xs.ahoi.hcxs.R;
import com.xs.ahoi.hcxs.adapter.MySimpleAdapter;
import com.xs.ahoi.hcxs.dao.BookDao;
import com.xs.ahoi.hcxs.dao.CollectPathDao;
import com.xs.ahoi.hcxs.dao.ConfigDao;
import com.xs.ahoi.hcxs.model.Book;
import com.xs.ahoi.hcxs.model.enums.FileTypeEnum;
import com.xs.ahoi.hcxs.model.vo.ImportFileItemVO;
import com.xs.ahoi.hcxs.ui.dialog.DialogCollectPath;
import com.xs.ahoi.hcxs.ui.dialog.DialogCollectPathList;
import com.xs.ahoi.hcxs.ui.dialog.DialogCommonTips;
import com.xs.ahoi.hcxs.utils.FileUtil;
import com.xs.ahoi.hcxs.utils.ThreadPoolFactory;
import com.xs.ahoi.hcxs.utils.ToastUtil;
import com.xs.ahoi.hcxs.utils.ViewUtil;
import com.xs.ahoi.hcxs.utils.ZipUtils;

import java.util.List;
import java.util.stream.Collectors;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnItemClick;
import butterknife.OnItemLongClick;

public class BookImportActivity extends BaseActivity {

    @BindView(R.id.lvPaths)
    public ListView lvPaths;
    @BindView(R.id.tvPath)
    public TextView tvPath;
    @BindView(R.id.tvPrevDir)
    public TextView tvPrevDir;
    @BindView(R.id.tvImportTips)
    public TextView tvImportTips;
    @BindView(R.id.tvAddToShelf)
    public TextView tvAddToShelf;
    @BindView(R.id.tvSelectAll)
    public TextView tvSelectAll;
    @BindView(R.id.tvDeleteSelect)
    public TextView tvDeleteSelect;
    @BindView(R.id.tvCollectPath)
    public TextView tvCollectPath;

    // listview数据集
    private List<ImportFileItemVO> datas;
    // 已选中的item
    private List<ImportFileItemVO> selectedDatas;
    // 所有可选的txt文件
    private List<ImportFileItemVO> allFileList;
    private ImportAdapter adapter;
    // 未选中图标， 已选中图标， 加入收藏图标
    private Drawable iconFile, iconFolder;
    private int itemSelectedBgColor, itemUnSelectedBgColor;
    // 根路径
    private String rootPath;
    private BookDao bookDao;
    private ConfigDao configDao;
    private CollectPathDao collectPathDao;
    // 已加入收藏的目录
    private List<String> collectPaths;
    // 弹出加入收藏或取消收藏
    private DialogCollectPath dialogCollectPath;
    // 通用的提示弹框
    private DialogCommonTips dialogCommonTips;
    // 弹出收藏目录列表
    private DialogCollectPathList dialogCollectPathList;
    private DialogCollectPathList.CollectPathListListener collectPathListListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_book_import);
        ButterKnife.bind(this);
        initListener();
        init();
    }

    private void init() {
        // 缓存工具
        configDao = ConfigDao.getInstance();
        collectPathDao = CollectPathDao.getInstance();

        // 数据库查询工具
        bookDao = BookDao.getInstance();

        // 初始化弹出加入收藏或取消收藏
        dialogCollectPath = new DialogCollectPath(this);

        // 初始化弹出收藏目录列表
        dialogCollectPathList = new DialogCollectPathList(this);
        dialogCollectPathList.setCollectPathListListener(collectPathListListener);

        // 通用的提示弹框
        dialogCommonTips = new DialogCommonTips(this);

        // 文件、文件夹图标
        iconFile = ContextCompat.getDrawable(this, R.drawable.icon_file);
        iconFolder = ContextCompat.getDrawable(this, R.drawable.icon_folder);
        itemSelectedBgColor = ContextCompat.getColor(this, R.color.colorDivider);
        itemUnSelectedBgColor = ContextCompat.getColor(this, R.color.colorWhite);
        selectedDatas = Lists.newArrayList();

        // 获取根目录
        rootPath = FileUtil.getSdCard();

        // 显示当前路径
        tvPath.setText(rootPath);

        // 渲染listView
        bindListView(rootPath);
    }

    // 初始化监听
    private void initListener() {
        collectPathListListener = new DialogCollectPathList.CollectPathListListener() {
            @Override
            public void moveToPath(String path) {
                bindListView(path);
            }

            @Override
            public void refresh() {
                collectPaths = collectPathDao.listAll();
                adapter.refresh(datas);
            }
        };
    }

    // 绑定列表数据
    private void bindListView(String path) {
        // 更新当前路径
        if (path == null) {
            path = getCurrentPath();
        } else {
            tvPath.setText(path);
            ViewUtil.autoSplitText(tvPath);
        }

        // 查询数据库已存在的书籍
        List<String> pathList = bookDao.listAll().stream().map(Book::getPath).collect(Collectors.toList());

        // 获取根目录下的子目录
        datas = FileUtil.getAllFiles(path);

        // 已加入收藏的目录
        collectPaths = collectPathDao.listAll();

        // 标记当前目录下已导入的
        datas.stream()
                .filter(o -> pathList.contains(o.getPath()))
                .forEach(o -> o.setImported(true));

        // 获取本目录可以导入的文件
        allFileList = datas.stream()
                .filter(o -> FileTypeEnum.FILE.equals(o.getFileType()))
                .collect(Collectors.toList());

        // 绑定到listview
        adapter = new ImportAdapter(this, datas, R.layout.listview_item_import);
        lvPaths.setAdapter(adapter);

        // 监听滚动时显示首字母
        String finalPath = path;
        lvPaths.setOnScrollListener(new AbsListView.OnScrollListener() {
            // 变量作用是避免第一次打开时会自动执行onscroll方法而无法默认隐藏tvImportTips
            boolean visible = false;

            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                // scrollState有三种状态，分别是开始滚动（SCROLL_STATE_FLING），正在滚动(SCROLL_STATE_TOUCH_SCROLL), 已经停止（SCROLL_STATE_IDLE）
                if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                    new Handler().postDelayed(() -> tvImportTips.setVisibility(View.INVISIBLE), 1000);
                    visible = false;

                    // 滚动停止时更新当前listview的滚动位置
                    configDao.setImportScrollPosition(finalPath, lvPaths.getFirstVisiblePosition());
                } else {
                    visible = true;
                }
            }

            @Override
            public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (visible) {
                    tvImportTips.setText(datas.get(firstVisibleItem).getName().substring(0, 1).toUpperCase());
                    tvImportTips.setVisibility(View.VISIBLE);
                }
            }
        });

        // 滚动到上次的位置
        lvPaths.setSelection(configDao.getImportScrollPosition(path));

        // 刷新当前页面下方按钮文字
        selectedDatas.clear();
        updateView();

        // 控制是否显示[上一级]按钮
        if (!rootPath.equals(getCurrentPath())) {
            tvPrevDir.setVisibility(View.VISIBLE);
        }
    }

    private String getCurrentPath() {
        return tvPath.getText().toString().replaceAll("\n", "");
    }

    // 返回上一级目录
    private boolean returnPrevPath() {
        String currentPath = getCurrentPath();

        if (rootPath.equals(currentPath)) {
            return false;
        }

        String newPath = currentPath.substring(0, currentPath.lastIndexOf("/"));
        bindListView(newPath);

        // 隐藏[上一级]按钮
        if (rootPath.equals(newPath)) {
            tvPrevDir.setVisibility(View.INVISIBLE);
        }
        return true;
    }

    @OnClick({R.id.tvPrevDir, R.id.tvAddToShelf, R.id.tvSelectAll, R.id.tvDeleteSelect,
            R.id.arrowLeft, R.id.tvCollectPath})
    public void onClick(View v) {
        List<String> pathList = selectedDatas.stream().map(ImportFileItemVO::getPath).collect(Collectors.toList());
        switch (v.getId()) {
            // 返回上一级
            case R.id.tvPrevDir:
                returnPrevPath();
                break;
            // 删除选中文件
            case R.id.tvDeleteSelect:
                // 删除本地文件
                FileUtil.delete(pathList);
                // 删除数据库
                bookDao.deleteByPath(pathList);
                bindListView(null);
                break;
            // 加入书架
            case R.id.tvAddToShelf:
                if (selectedDatas.isEmpty()) {
                    ToastUtil.show("您还没有选择");
                } else if (selectedDatas.stream().anyMatch(ImportFileItemVO::canNotImport)) {
                    ToastUtil.show("已导入的或非文本文件不能导入");
                } else {
                    // 保存到数据库
                    List<Book> books = Lists.newArrayList();
                    for (ImportFileItemVO o : selectedDatas) {
                        Book book = new Book();
                        book.setPath(o.getPath());
                        book.setName(o.getName());
                        book.setTotalLenth(FileUtil.getFile(o.getPath()).length());
                        books.add(book);
                    }
                    bookDao.save(books);
                    ToastUtil.show("已导入 " + selectedDatas.size() + " 本书至书架");

                    // 更新页面
                    bindListView(null);
                }
                break;
            // 全选
            case R.id.tvSelectAll:
                if (allFileList.isEmpty()) {
                    ToastUtil.show("没有可选项");
                } else {
                    if (selectedDatas.size() < allFileList.size()) {
                        selectedDatas.clear();
                        selectedDatas.addAll(allFileList);
                    } else {
                        selectedDatas.clear();
                    }
                    updateView();
                }
                break;
            // 左上角返回键
            case R.id.arrowLeft:
                super.onBackPressed();
                break;
            // 收藏目录
            case R.id.tvCollectPath:
                if (collectPathDao.listAll().size() == 0) {
                    ToastUtil.show("未收藏任何目录~");
                } else {
                    dialogCollectPathList.show();
                }
                break;
            default:
                break;
        }
    }

    @OnItemClick({R.id.lvPaths})
    public void onItemClick(int position) {

        // 获取点击的路径名
        ImportFileItemVO item = datas.get(position);

        // 如果是文件，则勾选复选框，并显示加入书架view
        if (FileTypeEnum.FILE.equals(item.getFileType())) {
            if (selectedDatas.contains(item)) {
                selectedDatas.remove(item);
            } else {
                selectedDatas.add(item);
            }
            updateView();
        } else {
            // 显示上一级按钮
            if (tvPrevDir.getVisibility() == View.INVISIBLE) {
                tvPrevDir.setVisibility(View.VISIBLE);
            }

            // 根据点击路径加载下级目录
            bindListView(item.getPath());
        }
    }

    @OnItemLongClick({R.id.lvPaths})
    public boolean onItemLongClick(View view, int position) {

        // 长按文件夹时，显示加入收藏的弹框
        ImportFileItemVO item = datas.get(position);

        switch (item.getFileType()) {
            case FILE:
                if (!item.isZip()) {
                    break;
                }
                dialogCommonTips.setListener(() -> {
                    Boolean b = ZipUtils.unCompress(item.getPath());
                    ToastUtil.show(b == null ? "只支持zip和rar格式~" : (b ? "解压成功~" : "文件已损坏，解压失败"));
                    bindListView(null);
                });
                dialogCommonTips.show("是否解压到当前目录？");
                break;
            case FOLDER:
                if (position <= lvPaths.getFirstVisiblePosition()) {
                    dialogCollectPath.setBottom();
                } else {
                    dialogCollectPath.setTop();
                }
                if (collectPaths.contains(item.getPath())) {
                    dialogCollectPath.showRemove();
                } else {
                    dialogCollectPath.showAdd();
                }
                dialogCollectPath.setClickedView(view);
                dialogCollectPath.setClickListener(new DialogCollectPath.Listener() {
                    @Override
                    public void add() {
                        // 点击后保存入库，并隐藏弹框
                        ThreadPoolFactory.getInstance().execute(() -> collectPathDao.save(item.getPath()));
                        dialogCollectPath.dismiss();
                        collectPaths.add(item.getPath());
                        updateView();
                        ToastUtil.show("已加入收藏");
                    }

                    @Override
                    public void remove() {
                        // 点击后删除收藏库中的本路径，并隐藏弹框
                        ThreadPoolFactory.getInstance().execute(() -> collectPathDao.deleteByPath(item.getPath()));
                        dialogCollectPath.dismiss();
                        collectPaths.remove(item.getPath());
                        updateView();
                        ToastUtil.show("已取消收藏");
                    }
                });
                dialogCollectPath.show();
                break;
            default:
                break;
        }
        return true;
    }

    // 更新listview和加入书架按钮
    private void updateView() {
        adapter.refresh(datas);

        if (selectedDatas.size() < allFileList.size() || allFileList.size() == 0) {
            tvSelectAll.setText(getString(R.string.select_all));
        } else {
            tvSelectAll.setText(getString(R.string.cancel));
        }

        if (selectedDatas.size() > 0) {
            tvAddToShelf.setText(getString(R.string.add_to_shelf) + "(" + selectedDatas.size() + ")");
            tvDeleteSelect.setText(getString(R.string.delete) + "(" + selectedDatas.size() + ")");
        } else {
            tvAddToShelf.setText(getString(R.string.add_to_shelf));
            tvDeleteSelect.setText(getString(R.string.delete));
        }
    }

    @Override
    public void onBackPressed() {
        if (!returnPrevPath()) {
            super.onBackPressed();
        }
    }

    // 自定义SimpleAdapter
    private class ImportAdapter extends MySimpleAdapter<ImportFileItemVO> {

        private ImportAdapter(Context context, List<ImportFileItemVO> datas, int resource) {
            super(context, datas, resource);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View view = super.getView(position, convertView, parent);
            ImageView ivFileTypeImg = view.findViewById(R.id.ivFileTypeImg);
            TextView tvFileName = view.findViewById(R.id.tvFileName);
            TextView tvFileSize = view.findViewById(R.id.tvFileSize);
            TextView tvFileStatus = view.findViewById(R.id.tvFileStatus);

            ImportFileItemVO item = getItem(position);
            ivFileTypeImg.setBackground(FileTypeEnum.FILE.equals(item.getFileType()) ? iconFile : iconFolder);
            tvFileName.setText(item.getName());
            tvFileSize.setText(item.getSize());
            tvFileStatus.setVisibility(View.VISIBLE);

            if (selectedDatas.contains(item)) {
                view.setBackgroundColor(itemSelectedBgColor);
            } else {
                view.setBackgroundColor(itemUnSelectedBgColor);
            }

            // 如果是文件，设置图标，否则设置空背景
            if (FileTypeEnum.FILE.equals(item.getFileType())) {
                if (item.isZip()) {
                    tvFileStatus.setText("长按解压");
                } else if (item.isImported()) {
                    tvFileStatus.setText("已导入");
                } else {
                    tvFileStatus.setVisibility(View.GONE);
                }
            } else {
                // 如果是已经在收藏目录，则显示收藏图标
                if (collectPaths.contains(item.getPath())) {
                    tvFileStatus.setText("已收藏");
                } else {
                    tvFileStatus.setVisibility(View.GONE);
                }
            }
            return view;
        }
    }
}
